package com.gxkj.drm.service;


import com.gxkj.drm.dao.ResourceManageDao;
import com.gxkj.drm.entitys.ResourceManage;
import com.gxkj.drm.enums.SendType;
import com.gxkj.drm.uitls.ThreadUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;


/**
 * 资源管理服务
 * @author shaoxiangfei
 *
 */
@Service
public class ResourceManageService {

    @Autowired
    private ResourceManageDao resourceManageDao;

    @Autowired
    private PushMananger pushMananger;

    private static final String PATH_ATTR_FORMART = "%s:%s";
    private static final String NOT_PUSH = "NOT_PUSH";

    public int pushAllAttributeValue(String cluster, String attribute, String attributeValue, SendType sentType) {
        List<ResourceManage> rmList = this.resourceManageDao.getResourceManageByAttribute(cluster, attribute);

        if (CollectionUtils.isEmpty(rmList) || StringUtils.isBlank(attributeValue)) {
            return 0;
        }

        int count = 0;

        List<Callable<Boolean>> batchSendCallList = new ArrayList<>();

        for (ResourceManage rm : rmList) {
            rm.setAttributeOldValue(rm.getAttributeValue());
            rm.setAttributeValue(attributeValue);
            Callable callable = new SendAttrCallable(rm, sentType);
            batchSendCallList.add(callable);
        }

        List<Boolean> callResultList = ThreadUtil.submit(batchSendCallList, 10000L);

        for(Boolean bl : callResultList) {
            if(bl.equals(Boolean.TRUE)) {
                count ++;
            }
        }

        if (count == rmList.size()) {
            return 0;
        } else if (count > 0) {
            return 1;
        } else {
            return 2;
        }
    }

    private class SendAttrCallable implements Callable<Boolean> {

        private ResourceManage rm;

        private SendType sendType;

        SendAttrCallable(ResourceManage rm, SendType sendType) {
            this.rm = rm;
            this.sendType = sendType;
        }

        @Override
        public Boolean call() throws Exception {
            if (pushMananger.sendAttributeValue(rm, sendType)) {
                resourceManageDao.updateResourceManageOldAttributeValue(rm);

                return true;
            }

            return false;
        }
    }


    public boolean pushAttributeValue(long id, String attributeValue) {
        ResourceManage rm = this.resourceManageDao.getResourceManageById(id);

        if (rm == null || StringUtils.isBlank(attributeValue)) {
            return true;
        }

        rm.setAttributeOldValue(rm.getAttributeValue());
        rm.setAttributeValue(attributeValue);

        if (this.pushMananger.sendAttributeValue(rm, SendType.SEND)) {
            this.resourceManageDao.updateResourceManageOldAttributeValue(rm);

            return true;
        }

        return false;
    }

    public List<ResourceManage> getResourceManageByAttribute(String cluster, String attribute) {
        return this.resourceManageDao.getResourceManageByAttribute(cluster, attribute);
    }

    public List<ResourceManage> getResourceManageByIp(String cluster, String ip) {
        return this.resourceManageDao.getResourceManageByIp(cluster, ip);
    }

    @Transactional
    public boolean dealResourceManageInfo(String cluster, String ip, List<ResourceManage> resourceManageList) {
        if (StringUtils.isBlank(cluster) || StringUtils.isBlank(ip)) {
            return true;
        }

        if (CollectionUtils.isEmpty(resourceManageList)) {
            //删除集群，ip,对应的资源
            this.resourceManageDao.deleteResourceByIp(cluster, ip);
            return true;
        }

        Map<String, String> newAttributeMap = new HashMap<>(); //服务重新推送过来的属性值
        List<ResourceManage> pushResourceManageList = new ArrayList<ResourceManage>(); //要推送原先属性值的
        List<String> pushAttributeList = new ArrayList<String>(); //要推送的属性名
        List<ResourceManage> addResourceManageList = new ArrayList<ResourceManage>(); //新增的属性
        List<Long> deleteResourceIdList = new ArrayList<Long>(); //要删除的属性
        // 不接收推送的属性
        List<ResourceManage> notPushResourceManageList = new ArrayList<>();

        for (ResourceManage rm : resourceManageList) {
            rm.setIp(ip);
            rm.setCluster(cluster);
            newAttributeMap.put(String.format(PATH_ATTR_FORMART, rm.getResourcePath(), rm.getAttribute()), rm.getAttributeValue());
        }

        //从数据库获取服务器老的属性信息
        List<ResourceManage> oldResourceManageList = this.resourceManageDao.getResourceManageByFullIp(cluster, ip);
        for (ResourceManage rm : oldResourceManageList) {
            String key = String.format(PATH_ATTR_FORMART, rm.getResourcePath(), rm.getAttribute());
            if (newAttributeMap.containsKey(key)) {
                if (StringUtils.isNotBlank(rm.getAttributeValue())) {
                    if (NOT_PUSH.equals(newAttributeMap.get(key))) {
                        rm.setAttributeOldValue(null);
                        rm.setAttributeValue(null);
                        notPushResourceManageList.add(rm);
                    } else {
                        pushResourceManageList.add(rm);
                    }
                }
                pushAttributeList.add(rm.getAttribute());
            } else {

                deleteResourceIdList.add(rm.getId());
            }
        }

        for (ResourceManage rm : resourceManageList) {
            if (!pushAttributeList.contains(rm.getAttribute())) {
                addResourceManageList.add(rm);
            }
        }

        if (!CollectionUtils.isEmpty(deleteResourceIdList)) {
            //批量删除
            this.resourceManageDao.batchDeleteResource(deleteResourceIdList);
        }

        if (!CollectionUtils.isEmpty(addResourceManageList)) {
            //批量新增
            this.resourceManageDao.batchInsertResource(addResourceManageList);
        }

        // 只更新数据库，不进行推送
        for (ResourceManage rm : notPushResourceManageList) {
            this.resourceManageDao.updateResourceManageOldAttributeValue(rm);
        }

        for (ResourceManage rm : pushResourceManageList) {
            if (this.pushMananger.sendAttributeValue(rm, SendType.INIT)) {//发送信息
                this.resourceManageDao.updateResourceManageOldAttributeValue(rm);//设置信息
            }
        }

        return true;
    }

    /**
     * 根据集群名称查询信息
     * @param clusterList
     * @return
     */
    public List<ResourceManage> getResourceManageByClusterList(List<String> clusterList) {
        return this.resourceManageDao.getResourceManageByClusterList(clusterList);
    }

    /**
     * 根据cluster、ip、属性参数查询
     */
    public List<ResourceManage> getResourceManageByParams(List<String> cluster, String ip, String attribute) {
        return this.resourceManageDao.getResourceManageByParams(cluster, ip, attribute);
    }

    /**
     * 根据Id查询
     */
    public ResourceManage getResourceManageById(long id) {
        return this.resourceManageDao.getResourceManageById(id);
    }

    /**
     * 获取集群名称列表
     */
    public List<String> getClusterList() {
        return this.resourceManageDao.getClusterList();
    }

}
